import hashlib
import time
from typing import Dict, Any

# from app.src.entity.goods_query import CommonParameters


# 依赖项：获取当前毫秒级时间戳
def get_current_timestamp():
    # 获取当前UNIX时间戳（UTC，秒级，取整为10位整数）
    current_timestamp = int(time.time())
    # 验证时间误差（与旺店通服务端误差≤5分钟，即300秒）
    # （注：实际需与服务端时间同步，此处仅示例本地计算）
    return current_timestamp


def md5_file(params: object) -> str:
    appsecret = "dc8394d168a8d540d0dfbd096fd8c9d7"  # 劲牛-酱香农资 接口密钥
    # 转换非字符串值为字符串，并拼接键=值-键=值
    # 获取所有键值对
    items = list(params.items())
    # 输出：[('appkey', 'test2-xx'), ('end_time', '2016-08-01 13:00:00'), ('page_no', 0), ...]
    file_path = ""
    # 遍历键值对
    for key, value in items:
        item = format_appkey_length(key)
        formatted = f"{key}={value}"
        itemValue = format_appkey2_length(str(value))
        # itemStr = item + "-" + key + ":" + itemValue + "-" + formatted
        itemStr = item + "-" + key + ":" + itemValue +"-"+ str(value)
        if key != "appkey":
            file_path = file_path + ";" + itemStr
        else:
            file_path = itemStr
    file_path = file_path + appsecret
    """计算文件的 MD5 值"""
    try:
        """
        生成32位小写的MD5值
        参数:
        text (str): 需要加密的字符串
        返回:
        str: 32位小写MD5值
        """
        # 创建MD5对象
        md5_hash = hashlib.md5()

        # 更新哈希对象内容（需要将字符串编码为字节）
        md5_hash.update(file_path.encode('utf-8'))

        # 获取十六进制表示的哈希值（32位小写）
        return md5_hash.hexdigest()

    except Exception as e:
        return ""


# appkey 采用utf8编码格式的字符长度并保留两位，不够的位数补0，计算结果为：06
def format_appkey_length(appkey: str) -> str:
    """
    计算appkey的UTF-8编码长度并格式化为两位字符串（不足补零）

    参数:
    appkey (str): 需要计算长度的字符串

    返回:
    str: 格式化后的长度字符串，例如"06"、"15"
    """
    # 计算UTF-8编码后的字节长度
    length = len(appkey.encode('utf-8'))

    # 格式化为两位数字，不足补零
    return f"{length:02d}"


# test2-xx 采用utf8编码格式的字符长度不足四位，保留四位，不够的位数补0，计算结果为：0008，如果超过4位，保留实际结果，如：10000
def format_appkey2_length(appkey: str) -> str:
    """
    计算appkey的UTF-8编码长度并格式化
    - 长度不足四位时，保留四位并左侧补零
    - 长度超过四位时，保留实际长度

    参数:
    appkey (str): 需要计算长度的字符串

    返回:
    str: 格式化后的长度字符串，例如"0008"、"10000"
    """
    # 计算UTF-8编码后的字节长度
    length = len(appkey.encode('utf-8'))

    # 根据长度决定格式化方式
    if length < 10000:
        return f"{length:04d}"  # 不足四位补零
    else:
        return str(length)  # 超过四位保留原样


def format_key_length(key: str) -> str:
    """计算键名UTF-8编码长度并格式化为两位字符串（不足补零）"""
    length = len(key.encode('utf-8'))
    return f"{length:02d}"

def format_value_length(value: str) -> str:
    """计算值的UTF-8编码长度并格式化（不足四位补零，超过保持原值）"""
    length = len(str(value).encode('utf-8'))
    return f"{length:04d}" if length < 10000 else str(length)

def generate_sign(params: Dict[str, Any], appsecret: str) -> str:
    """生成旺店通API签名"""
    # 1. 按键名正序排序
    sorted_params = dict(sorted(params.items()))
    
    # 2. 构建签名字符串
    sign_parts = []
    
    for key, value in sorted_params.items():
        # 转换值为字符串
        str_value = str(value)
        
        # 计算长度
        key_len = format_key_length(key)
        value_len = format_value_length(str_value)
        
        # 构建部分
        part = f"{key_len}-{key}:{value_len}-{str_value}"
        sign_parts.append(part)
    
    # 用分号连接各部分，最后一个不需要分号
    sign_str = ";".join(sign_parts)
    
    # 3. 添加appsecret
    sign_str += appsecret
    
    # 4. MD5加密（32位小写）
    return hashlib.md5(sign_str.encode('utf-8')).hexdigest()

def sign_util(start_time: str, end_time: str, page_no: int, page_size: int) -> Dict[str, str]:
    """生成API调用参数"""
    params = {
        'sid': 'ltsy2',          # 确保这个值是正确的店铺ID
        'appkey': 'ltsy2-gw2',   # 确保这个值是正确的应用key
        'timestamp': str(int(time.time())),
        'start_time': start_time,
        'end_time': end_time,
        'page_no': str(page_no),
        'page_size': str(page_size)
    }
    
    sign = generate_sign(params, "dc8394d168a8d540d0dfbd096fd8c9d7")
    params['sign'] = sign
    
    return params

# 测试代码
if __name__ == "__main__":
    # 使用示例中的测试数据
    test_params = {
        'appkey': 'test2-xx',
        'end_time': '2016-08-01 13:00:00',
        'page_no': '0',
        'page_size': '40',
        'sid': 'test2',
        'start_time': '2016-08-01 12:00:00',
        'timestamp': '1470042310'
    }
    
    # 测试签名生成
    test_sign = generate_sign(test_params, '12345')
    print(f"Generated sign: {test_sign}")
    print(f"Expected sign: ad4e6fe037ea6e3ba4768317be9d1309")
    print(f"Sign matches: {test_sign == 'ad4e6fe037ea6e3ba4768317be9d1309'}")
